package com.iretailer.report.quartz.hotwind;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.iretailer.report.influxdb.model.Passengerflow;
import com.iretailer.report.influxdb.service.InfluxdbFlowService;
import com.iretailer.report.influxdb.util.TableName;
import com.iretailer.report.mapper.CameraZoneMapper;
import com.iretailer.report.model.CameraZoneMd;
import com.iretailer.report.quartz.model.QuartTask;
import com.iretailer.report.service.QuartTaskService;
import com.iretailer.report.util.CommonUtil;
import com.iretailer.report.util.StringUtil;
import com.iretailer.report.util.TimeUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @Program: report
 * @Description:
 * @Author: Bennie
 * @Date: 2021-03-05 10:57
 **/

@Slf4j
@RequiredArgsConstructor
@Component("hotwindDataSender")
public class DataSender {

    private final CameraZoneMapper cameraZoneMapper;

    private final InfluxdbFlowService influxdbFlowService;

    private final QuartTaskService quartTaskService;

    public void execute() {
        log.info("---------开始执行热风数据发送任务---------");
        QuartTask task = quartTaskService.getOne(new QueryWrapper<QuartTask>().lambda()
                .eq(QuartTask::getSpringId, "hotwindDataSender")
                .eq(QuartTask::getJobName, "hotwindDataSender"));
        String otherMessage = task.getOtherMessage();
        long period = 5L;
        int retryTime = 3;
        String timezone = "Asia/Shanghai";
        String url = "http://test2.hotwind.net/api/Shop/Stream";
        if (StringUtil.notEmpty(otherMessage)) {
            JSONObject json = JSONUtil.parseObj(otherMessage);
            retryTime = json.getInt("retryTime" , 3);
            period = json.getLong("period" , 5L);
            timezone = json.getStr("timezone" , "Asia/Shanghai");
            url = json.getStr("url" , "http://test2.hotwind.net/api/Shop/Stream");
        }
        QueryWrapper<?> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("enabled" , "1");
        List<CameraZoneMd> cameraZoneMds = cameraZoneMapper.selectCameraZone(queryWrapper);
        Map<String, List<CameraZoneMd>> deviceMapData = cameraZoneMds.stream()
                .collect(Collectors.groupingBy(CameraZoneMd::getDeviceId));
        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime startTime = endTime.minusMinutes(period);
        for (String deviceId : deviceMapData.keySet()) {
            List<CameraZoneMd> zoneMds = deviceMapData.get(deviceId);
            List<Long> zoneIds = zoneMds.stream().map(CameraZoneMd::getId).collect(Collectors.toList());
            if (CommonUtil.isNotEmpty(zoneMds)) {
                CameraZoneMd cameraZoneMd = zoneMds.get(0);
                String mallCode = cameraZoneMd.getMallCode();
                String mallName = cameraZoneMd.getMallName();
                String physicalzoneName = cameraZoneMd.getPhysicalzoneName();
                List<Passengerflow> passengerflows = influxdbFlowService.selectFlowGrid(
                        timezone, TableName.Passengerflow.Passengerflow,
                        zoneIds, TimeUtil.localDateTime_format(startTime),
                        TimeUtil.localDateTime_format(endTime));
                Map<String, Object> params = new HashMap<String, Object>() {
                    {
                        put("ReqSeq" , UUID.randomUUID().toString().replaceAll("-" , ""));
                        put("StoreCode" , StringUtil.notEmpty(mallCode) ? mallCode : mallName.substring(0, 8));
                        put("BusinessTime" , TimeUtil.localDateTime_format(LocalDateTime.now()));
                        put("InShopNum" , passengerflows.stream().map(Passengerflow::getCountEnter).reduce(0, Integer::sum));
                        put("OverShopNum" , passengerflows.stream().map(Passengerflow::getCountExit).reduce(0, Integer::sum));
                        put("DeviceSeq" , deviceId);
                        put("DevicePosition" , physicalzoneName);
                    }
                };
                HttpRequest request = HttpUtil.createPost(url).body(JSONUtil.toJsonStr(params),
                        "application/json; charset=utf-8");
                int tryTime = 0;
                boolean success = false;
                do {
                    HttpResponse response = null;
                    try {
                        response = request.execute();
                    } catch (Exception e) {
                        log.error(String.format("热风发送数据失败【%s】" , url), e);
                    }
                    Integer errorCode = 0;
                    String message = "";
                    if (response != null) {
                        JSONObject jsonResponse = JSONUtil.parseObj(response.body());
                        errorCode = jsonResponse.getInt("errorCode");
                        message = jsonResponse.getStr("message" , "");
                        success = response.isOk();
                    }
                    if (success) {
                        if (errorCode == 0) {
                            log.info("热风发送数据成功 {} {} 【{}】" , physicalzoneName, startTime, message);
                            break;
                        }
                    } else {
                        log.error("热风发送数据失败 {} {} 【{}】【重试次数 {}】" , physicalzoneName, startTime, message, tryTime);
                        tryTime++;
                    }
                } while (!success && tryTime < retryTime);

            }
        }
        log.info("---------热风数据发送任务执行完毕---------");
    }

}
